<template>
  <div class="json_wrap">
        <Splitpanes class="default-theme splitpanes_custom_theme" style="height: 100%" :dbl-click-splitter="false">
            <Pane size="50" min-size="20">
              <div class="json_left_wrap">
                <Textarea :bordered="false" v-model:value="jsonStr" @change="changeJsonContentFn" placeholder="请键入需要处理的json字符串" class="custom_textarea" allow-clear />
              </div>
            </Pane>
            <Pane size="50" max-size="70" min-size="20">
              <div class="json_content">
                    <div class="json_header_tool">
                      <div class="flex items-center justify-end flex-row tracking-widest leading-4">
                        <div class="text-base leading-4">
                          <Tooltip placement="topLeft">
                            <template #title>
                              <span>行号</span>
                            </template>
                            <ProfileOutlined :class="jsonConfig.showLineNumber ?'text-emerald-500':''"  @click="changeConfig('showLineNumber')" />
                          </Tooltip>
                        </div>
                        <div class="text-base leading-4 ml-3">
                          <Tooltip placement="topLeft">
                            <template #title>
                              <span>折叠</span>
                            </template>
                            <VerticalAlignMiddleOutlined :class="jsonConfig.collapsedOnClickBrackets ?'text-emerald-500':''"  @click="changeConfig('collapsedOnClickBrackets')" />
                          </Tooltip>
                        </div>
                        <div class="text-base leading-4 ml-3">
                          <Tooltip placement="topLeft">
                            <template #title>
                              <span>连接线</span>
                            </template>
                            <DeploymentUnitOutlined :class="jsonConfig.showLine ?'text-emerald-500':''"  @click="changeConfig('showLine')" />
                          </Tooltip>
                        </div>
                        <div class="text-base leading-4 ml-3">
                          <Tooltip placement="topLeft">
                            <template #title>
                              <span>闭合显示元素长度</span>
                            </template>
                            <SortAscendingOutlined :class="jsonConfig.showLength ?'text-emerald-500':''"  @click="changeConfig('showLength')" />
                          </Tooltip>
                        </div>
                        <div class="text-base leading-4 ml-3">
                          <Tooltip placement="topLeft">
                            <template #title>
                              <span>编辑</span>
                            </template>
                            <FormOutlined :class="jsonConfig.editable ?'text-emerald-500':''"  @click="changeConfig('editable')" />
                          </Tooltip>
                        </div>
                        <div class="text-base leading-4 ml-3">
                          <Tooltip placement="topLeft" color="green" @openChange="openShowItemHieght">
                            <template #title>
                              <div>
                                <!-- <p>行高</p> -->
                                <InputNumber placeholder="行高" v-model:value="jsonConfig.itemHeight" :min="20" :max="100" />
                              </div>
                              
                            </template>
                            <ColumnHeightOutlined />
                          </Tooltip>
                        </div>

                        
                        <div class="text-base leading-4 ml-3">
                          <Tooltip placement="topLeft">
                            <template #title>
                              <span>清空</span>
                            </template>
                            <DeleteOutlined @click="clearContent" />
                          </Tooltip>
                        </div>
                      </div>
                      <div class="flex items-center justify-end flex-row border-slate-300 border text-xs tracking-widest leading-4 rounded">
                        <span @click="compressJson" class="flex items-center whitespace-nowrap p-1 border-solid cursor-pointer border-r border-slate-300">
                          <FileSyncOutlined  class="mr-1" />
                          压缩
                        </span>
                        <span @click="saveAsTxt" class="flex items-center whitespace-nowrap p-1 border-solid cursor-pointer border-r border-slate-300">
                          <CloudDownloadOutlined class="mr-1" />
                          保存
                        </span>
                        <span @click="handleCopyBtnClick" class="flex items-center whitespace-nowrap p-1 cursor-pointer">
                          <CopyOutlined class="mr-1" />
                          复制
                        </span>
                      </div>
                    </div>
                    <div class="json_right_content" >
                      <Empty v-if="!renderJsonStr" description="暂无数据">
                        <template #image>
                          <simpleImage />
                        </template>
                      </Empty>
                      <template v-else>
                        <vue-json-pretty
                        class="json_tree_wrap"
                        v-model:data="renderJsonStr"
                        :deep="jsonConfig.deep"
                        :show-double-quotes="jsonConfig.showDoubleQuotes"
                        :show-length="jsonConfig.showLength"
                        :show-line="jsonConfig.showLine"
                        :show-line-number="jsonConfig.showLineNumber"
                        :collapsed-on-click-brackets="jsonConfig.collapsedOnClickBrackets"
                        :show-icon="jsonConfig.showIcon"
                        :show-key-value-space="jsonConfig.showKeyValueSpace"
                        :editable="jsonConfig.editable"
                        :editable-trigger="jsonConfig.editableTrigger"
                        :item-height="jsonConfig.itemHeight"
                        :show-select-controller="jsonConfig.showSelectController"
                        >

                      </vue-json-pretty>
                      </template>
                    </div>
              </div>
            </Pane>
        </Splitpanes>
  </div>
</template>
<script lang="ts" setup>
import {
  Textarea,
  Empty,
  message,
  Tooltip,
  InputNumber
} from "ant-design-vue";
import { CopyOutlined,CloudDownloadOutlined} from "@ant-design/icons-vue";
import { ref,defineAsyncComponent, reactive,watch } from "vue";
const VueJsonPretty = defineAsyncComponent(() => import('vue-json-pretty').then(module => module));
const Splitpanes = defineAsyncComponent(() => import('splitpanes').then(module => module.Splitpanes));
const Pane = defineAsyncComponent(() => import('splitpanes').then(module => module.Pane));
import json5 from 'json5'
import 'splitpanes/dist/splitpanes.css';
import 'vue-json-pretty/lib/styles.css';
import { useClipboard } from '@vueuse/core'
import {saveTxt} from '@/utils/tool'
import {debounce} from 'lodash'


const simpleImage = Empty.PRESENTED_IMAGE_SIMPLE;
const jsonConfig:any = reactive({
    showLength: true,
    showLine: true,
    showLineNumber: true,
    showDoubleQuotes: true,/* 是否key名显示双引号 */
    collapsedOnClickBrackets: true,/* 是否支持折叠 */
    useRenderNodeKeySlot: true,
    useRenderNodeValueSlot: true,
    deep: 4,
    setPathCollapsible: true,
    showIcon: true,
    showKeyValueSpace: true,
    showSelectController: true,
    editable:true,
    editableTrigger:"click",
    itemHeight:"auto",
    saveTime:500,/* 防抖间隙 */
})

const jsonStr = ref()
const renderJsonStr=ref()



const formatterJson = ()=>{
  try {
    // if(!jsonStr.value){
    //   renderJsonStr.value = ""
    //   return ;
    // }
    renderJsonStr.value = json5.parse(jsonStr.value);
  } catch (error) {
    message.destroy();
    message.error(`解析出错:${(error as any).message}`);
    // renderJsonStr.value = ""
  }
}

const changeJsonContentFn = debounce(formatterJson, jsonConfig.saveTime);

const compressJson = () => {
  try {
    jsonStr.value = JSON.stringify(renderJsonStr.value, null, "");
  }catch(e){
    console.log(e)
  }
}


const { copy } = useClipboard({ legacy: true })
function handleCopyBtnClick(text: string) {
  if (!renderJsonStr.value) {
    return message.error('请输入正确的复制内容！')
  }
  const jsonString = JSON.stringify(renderJsonStr.value)
  try {
    copy(jsonString)
    message.success('复制成功')
  }
  catch (e) {
    console.log(e)
    message.error('复制失败')
  }
}

const openShowItemHieght=(visible:boolean)=>{
  if(visible && jsonConfig.itemHeight === 'auto'){
    jsonConfig.itemHeight = 20;
  }
}

function clearContent(){
  jsonStr.value = undefined
  renderJsonStr.value = undefined
}

const changeConfig=(key:string)=>{
  jsonConfig[key] = !jsonConfig[key];
}


const jsonClick=(path:string, data:any)=>{
  console.log(path, data);
}

const saveAsTxt = () => {
  if (!renderJsonStr.value) return
  
  saveTxt(JSON.stringify(renderJsonStr.value,null,''),`json_${new Date().getTime()}.txt`)
 }

</script>
<style lang="scss" scoped>
@import './style.scss';
</style>
